/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "数学/数学.h"

#include <random>
#include <core/结构数据.h>



int8 f_random_I8(ivec2 区间, int32 种子) {
	std::mt19937 gen(种子);
	std::uniform_int_distribution<int32_t> distrib(DEF_Min(区间.x, 区间.y), DEF_Max(区间.x, 区间.y));

	return distrib(gen);
}

void f_random_I8Array(S_I8Array* val, uint64 num, int8 最小, int8 最大, int32 种子) {
	//std::uniform_real_distribution<int32> dis_x(int32(最小), int32(最大));
	std::mt19937 gen(种子);
	std::uniform_int_distribution<int32_t> distrib(DEF_Min(最小, 最大), DEF_Max(最小, 最大));

	if (num > 65536) {
	#pragma omp parallel for
		for (int64 i = 0; i < num; ++i) {
			val->ptr_userData[i] = distrib(gen);
		};
	}
	else {
		for (uint64 i = 0; i < num; ++i) {
			val->ptr_userData[i] = distrib(gen);
		}
	}
}

void f_random_F32Array(S_F32Array* vec, uint64 num, float32 最小, float32 最大, int32 种子) {
	std::uniform_real_distribution<float32> dis_x(最小, 最大);
	std::default_random_engine e(种子);

	if (num > 65536) {
#pragma omp parallel for
		for (int64 i = 0; i < num; ++i) {
			vec->ptr_userData[i] = dis_x(e);
		};
	}
	else {
		for (uint64 i = 0; i < num; ++i) {
			vec->ptr_userData[i] = dis_x(e);
		}
	}
}

void f_random_I32Array(S_I32Array* vec, uint64 num, float32 最小, float32 最大, int32 种子) {
	//std::uniform_real_distribution<int32> dis_x(int32(最小), int32(最大));
	std::mt19937 gen(种子);
	std::uniform_int_distribution<int32_t> distrib(最小, 最大);

	if (num > 65536) {
#pragma omp parallel for
		for (int64 i = 0; i < num; ++i) {
			vec->ptr_userData[i] = distrib(gen);
		};
	}
	else {
		for (uint64 i = 0; i < num; ++i) {
			vec->ptr_userData[i] = distrib(gen);
		}
	}
}

void f_random_UI32Array(S_UI32Array* vec, uint64 num, uint32 最小, uint32 最大, int32 种子) {
	//std::uniform_real_distribution<int32> dis_x(int32(最小), int32(最大));
	std::mt19937 gen(种子);
	std::uniform_int_distribution<uint32_t> distrib(最小, 最大);

	if (num > 65536) {
	#pragma omp parallel for
		for (int64 i = 0; i < num; ++i) {
			vec->ptr_userData[i] = distrib(gen);
		};
	}
	else {
		for (uint64 i = 0; i < num; ++i) {
			vec->ptr_userData[i] = distrib(gen);
		}
	}
}

void f_random_Vec3Array(S_Vec3Array* vec, uint64 num, vec2 X, vec2 Y, vec2 Z, int32 种子) {
	std::uniform_real_distribution<float32> dis_x(DEF_Min(X.x, X.y), DEF_Max(X.x, X.y));
	std::uniform_real_distribution<float32> dis_y(DEF_Min(Y.x, Y.y), DEF_Max(Y.x, Y.y));
	std::uniform_real_distribution<float32> dis_z(DEF_Min(Z.x, Z.y), DEF_Max(Z.x, Z.y));
	std::default_random_engine e(种子);

	f_core_array_resize((S_Array*)vec, num);
	
	if (num > 65535) {
#pragma omp parallel for
		for (int64 i = 0; i < num; ++i) {
			vec->ptr_userData[i] = vec3{ dis_x(e), dis_y(e), dis_z(e) };
		};
	}
	else {
		for (uint64 i = 0; i < num; ++i) {
			vec->ptr_userData[i] = vec3{ dis_x(e), dis_y(e), dis_z(e) };
		}
	}
}

void f_random_iVec2Array(S_iVec2Array* vec, uint64 num, const ivec2& X区间, const ivec2& Y区间, int32 种子, uint8 type) {
	f_core_array_resize((S_Array*)vec, num);

	int32 X最小区间 = DEF_Min(X区间.x, X区间.y);
	int32 X最大区间 = DEF_Max(X区间.x, X区间.y);

	int32 Y最小区间 = DEF_Min(Y区间.x, Y区间.y);
	int32 Y最大区间 = DEF_Max(Y区间.x, Y区间.y);

	switch (type) {
		case 0: {
			for (int64 i = 0; i < num; ++i) {
				vec->ptr_userData[i] = ivec2{ 种子, 种子 };
			}
			break;
		}
		case 1: {
			std::uniform_int_distribution<int32> dis_x(X最小区间, Y最大区间);
			std::uniform_int_distribution<int32> dis_y(Y最小区间, Y最大区间);
			std::default_random_engine e(种子);

			if (num > 65535) {
			#pragma omp parallel for
				for (int64 i = 0; i < num; ++i) {
					vec->ptr_userData[i] = ivec2{ dis_x(e), dis_y(e) };
				};
			}
			else {
				for (uint64 i = 0; i < num; ++i) {
					vec->ptr_userData[i] = ivec2{ dis_x(e), dis_y(e) };
				}
			}
			break;
		}
		case 2: {
			for (int32 i = 0; i < num; ++i) {
				vec->ptr_userData[i] = ivec2{ i, i };
			}
			break;
		}
		case 3: {
			float32 X步进 = float32(Y最大区间 - X最小区间) / num;
			float32 Y步进 = float32(Y最大区间 - Y最小区间) / num;
			for (int32 i = 0; i < num; ++i) {
				vec->ptr_userData[i] = ivec2{ int32(X步进*i), int32(Y步进*i) };
			}
			break;
		}
		default:
			break;
	}
}

void f_random_iVec3Array(S_iVec3Array* vec, uint64 num, const ivec3& 最小, const ivec3& 最大, int32 种子) {
	std::uniform_int_distribution<int32> dis_x(DEF_Min(最小.x, 最大.x), DEF_Max(最小.x, 最大.x));
	std::uniform_int_distribution<int32> dis_y(DEF_Min(最小.y, 最大.y), DEF_Max(最小.y, 最大.y));
	std::uniform_int_distribution<int32> dis_z(DEF_Min(最小.z, 最大.z), DEF_Max(最小.z, 最大.z));
	std::default_random_engine e(种子);

	f_core_array_resize((S_Array*)vec, num);

	if (num > 65535) {
	#pragma omp parallel for
		for (int64 i = 0; i < num; ++i) {
			vec->ptr_userData[i] = ivec3{ dis_x(e), dis_y(e), dis_z(e) };
		};
	}
	else {
		for (uint64 i = 0; i < num; ++i) {
			vec->ptr_userData[i] = ivec3{ dis_x(e), dis_y(e), dis_z(e) };
		}
	}
}





